<html>
  <head>
    <link rel="stylesheet" href="../../../../node_modules/mocha/mocha.css" />
    <!-- Loads polyfills but does not force settings... -->
    <meta name="manual-polyfills" />
    <script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
    <script src="../polyfill-support.js"></script>
    <script src="../lit.min.js"></script>
  </head>

  <body>
    <script type="module">
      // node resolution doesn't seem to be working here.
      import {
        mocha,
        sessionFinished,
        sessionFailed,
      } from '../../../node_modules/@web/test-runner-mocha/dist/standalone.js';
      import {assert} from '../node_modules/chai/index.js';
      import {
        getComputedStyleValue,
        generateElementName,
        nextFrame,
      } from '../node_modules/lit-element/development/test/test-helpers.js';

      try {
        // setup mocha
        mocha.setup({ui: 'tdd', timeout: 60000});

        const {LitElement, html} = window.Lit;

        suite('LitElement Bundle', () => {
          let container;

          setup(() => {
            container = document.createElement('div');
            document.body.appendChild(container);
          });

          teardown(() => {
            if (container && container.parentNode) {
              container.parentNode.removeChild(container);
            }
          });

          test('renders initial content into shadowRoot', async () => {
            const rendered = `hello world`;
            const name = generateElementName();
            customElements.define(
              name,
              class extends LitElement {
                render() {
                  return html`${rendered}`;
                }
              }
            );
            const el = document.createElement(name);
            container.appendChild(el);
            await el.updateComplete;
            assert.ok(el.shadowRoot);
            assert.include(el.shadowRoot.innerHTML, rendered);
          });

          test('updates/renders attributes, properties, and event listeners via `lit-html`', async () => {
            class E extends LitElement {
              render() {
                const attr = 'attr';
                const prop = 'prop';
                const event = function (e) {
                  this._event = e;
                };
                return html`<div
                  attr="${attr}"
                  .prop="${prop}"
                  @zug="${event}"
                ></div>`;
              }
            }
            customElements.define(generateElementName(), E);
            const el = new E();
            container.appendChild(el);
            await el.updateComplete;
            const d = el.shadowRoot.querySelector('div');
            assert.equal(d.getAttribute('attr'), 'attr');
            assert.equal(d.prop, 'prop');
            const e = new Event('zug');
            d.dispatchEvent(e);
            assert.equal(el._event, e);
          });

          test('content shadowRoot is styled', async () => {
            const name = generateElementName();
            customElements.define(
              name,
              class extends LitElement {
                render() {
                  return html` <style>
                      div {
                        border: 2px solid blue;
                      }
                    </style>
                    <div>Testing...</div>`;
                }
              }
            );
            const el = document.createElement(name);
            container.appendChild(el);
            await el.updateComplete;
            const div = el.shadowRoot.querySelector('div');
            assert.equal(
              getComputedStyleValue(div, 'border-top-width').trim(),
              '2px'
            );
          });

          test('custom properties flow to nested elements', async () => {
            customElements.define(
              'x-inner',
              class extends LitElement {
                render() {
                  return html` <style>
                      div {
                        border: var(--border);
                      }
                    </style>
                    <div>Testing...</div>`;
                }
              }
            );
            const name = generateElementName();
            class E extends LitElement {
              constructor() {
                super();
                // NOTE, don't use a class field here to be compatible with
                // apparent rules for transpilation for Safari 13.
                this.inner = null;
              }

              render() {
                return html` <style>
                    x-inner {
                      --border: 8px solid red;
                    }
                  </style>
                  <x-inner></x-inner>`;
              }

              firstUpdated() {
                this.inner = this.shadowRoot.querySelector('x-inner');
              }
            }
            customElements.define(name, E);
            const el = document.createElement(name);
            container.appendChild(el);

            // Workaround for Safari 9 Promise timing bugs.
            (await el.updateComplete) && (await el.inner.updateComplete);

            await nextFrame();
            const div = el.inner.shadowRoot.querySelector('div');
            assert.equal(
              getComputedStyleValue(div, 'border-top-width').trim(),
              '8px'
            );
          });
        });

        // run the tests, and notify the test runner after finishing
        mocha.run(() => {
          sessionFinished();
        });
      } catch (error) {
        console.error(error);
        // notify the test runner about errors
        sessionFailed(error);
      }
    </script>
    <div id="mocha"></div>
  </body>
</html>
